import { asyncRouterMap, constantRouterMap } from '@/router'
import Layout from '@/views/layout/Layout'
import MainLayout from '@/components/Layout/index'
import axios from 'axios'
import CryptoJS from '@/utils/menuAesJiaJM'

/**
 * 通过meta.role判断是否与当前用户权限匹配
 * @param roles
 * @param route
 */
function hasPermission(roles, route) {
  if (route.meta && route.meta.title) {
    return roles.some((role) => route.meta.title === role.code)
  } else {
    return true
  }
}

/**
 * 递归过滤异步路由表，返回符合用户角色权限的路由表
 * @param routes asyncRouterMap
 * @param roles
 */
function filterAsyncRouter(routes, roles) {
  const res = []
  routes.forEach((route) => {
    const tmp = { ...route }
    roles.forEach((role) => {
      if (tmp.meta && tmp.meta.title) {
        if (role.code === tmp.meta.title) {
          tmp.meta['name'] = role.name || ''
          tmp.meta['ename'] = role.ename || ''
        }
      }
      if (tmp.meta && tmp.meta.icon) {
        if (role.code === tmp.meta.title) {
          tmp.meta['icon'] = role.img || ''
        }
      }
    })
    if (hasPermission(roles, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRouter(tmp.children, roles)
      }
      res.push(tmp)
    }
  })
  return res
}

/**
 * 递归json配置中的所有路由，返回vue组件的路由
 * @param routerMap
 */
function integrateRouter(routerMap) {
  const accessedRouters = routerMap.filter((route) => {
    if (route.component) {
      if (route.component === 'LayoutMain') {
        route.component = MainLayout
      } else if (route.component === 'Layout') {
        route.component = Layout
      } else {
        var aa = ''
        aa = route.component // 先输出再在导入里使用
        route.component = loadView(aa)
      }
    }

    if (route.children && route.children.length) {
      route.children = integrateRouter(route.children)
    }
    return true
  })
  return accessedRouters
}

function loadView(view) {
  return (resolve) => require([`@/${view}`], resolve)
}
/**
 * 生成扁平化机构路由(仅两级结构)
 * @param {允许访问的路由Tree} accessRoutes
 * 路由基本机构:
 * {
 *   name: String,
 *   path: String,
 *   component: Component,
 *   redirect: String,
 *   children: [
 *   ]
 * }
 */
function generateFlatRoutes(accessRoutes) {
  const flatRoutes = []
  for (const item of accessRoutes) {
    let childrenFflatRoutes = []
    if (item.children && item.children.length > 0) {
      childrenFflatRoutes = castToFlatRoute(item.children, '')
    }

    // 一级路由是布局路由,需要处理的只是其子路由数据
    flatRoutes.push({
      name: item.name,
      path: item.path,
      component: item.component,
      redirect: item.redirect,
      children: childrenFflatRoutes
    })
  }

  return flatRoutes
}

/**
 * 将子路由转换为扁平化路由数组（仅一级）
 * @param {待转换的子路由数组} routes
 * @param {父级路由路径} parentPath
 */
function castToFlatRoute(routes, parentPath, flatRoutes = []) {
  for (const item of routes) {
    if (item.children && item.children.length > 0) {
      if (item.redirect && item.redirect !== 'noRedirect') {
        flatRoutes.push({
          name: item.name,
          path: (parentPath + '/' + item.path).substring(1),
          redirect: item.redirect,
          meta: item.meta
        })
      }
      castToFlatRoute(item.children, parentPath + '/' + item.path, flatRoutes)
    } else {
      flatRoutes.push({
        name: item.name,
        path: (parentPath + '/' + item.path).substring(1),
        component: item.component,
        meta: item.meta
      })
    }
  }

  return flatRoutes
}
const permission = {
  state: {
    routers: constantRouterMap,
    addRouters: [],
    rolesBtns: [],
    locationRouter: []
  },
  mutations: {
    SET_ROUTERS: (state, routers) => {
      state.addRouters = routers
      state.routers = constantRouterMap.concat(routers)
    },
    SET_BUTTONS: (state, btns) => {
      state.rolesBtns = btns
    },
    SET_LOCATIONROUTER: (state, routers) => {
      state.locationRouter = routers
    }
  },
  actions: {
    GenerateRoutes({ commit }, data) {
      return new Promise((resolve) => {
        const roles = data && data.length > 0 ? data : []
        let accessedRouters = ''
        // accessedRouters = filterAsyncRouter(asyncRouterMap, roles) // router.js中的路由
        accessedRouters = filterAsyncRouter(permission.state.locationRouter, roles) // json配置路由
        const flatRoutes = generateFlatRoutes(accessedRouters)
        commit('SET_ROUTERS', accessedRouters)
        resolve(flatRoutes)
      })
    },
    GenerateButtons({ commit }, data) {
      return new Promise((resolve) => {
        commit('SET_BUTTONS', data.split(','))
        resolve()
      })
    },
    GetLocationRouter({ commit }) {
      return new Promise((resolve) => {
        let name = ''
        try {
          name = location.host.indexOf('.') > -1 ? location.host.split('.')[0] : 'default'
        } catch (err) {
          name = 'default'
        }
        if (name === 'default') {
          axios.get(`${process.env.BASE_URL}defaultM.json`).then((res) => {
            commit('SET_LOCATIONROUTER', integrateRouter(JSON.parse(CryptoJS.$aesMenuJieMi(res.data.m))))
            resolve()
          })
        } else {
          axios
            .get(`${process.env.BASE_URL}${name}M.json?_t=${new Date().getTime()}`)
            .then((res) => {
              commit('SET_LOCATIONROUTER', integrateRouter(JSON.parse(CryptoJS.$aesMenuJieMi(res.data.m))))
              resolve()
            })
            .catch(() => {
              axios.get(`${process.env.BASE_URL}defaultM.json`).then((res) => {
                commit('SET_LOCATIONROUTER', integrateRouter(JSON.parse(CryptoJS.$aesMenuJieMi(res.data.m))))
                resolve()
              })
            })
        }
      })
    }
  }
}

export default permission
